$.fn.ECalendar = function(config){
        var con = {
            offset : [0,0],
            type : 1,
            skin : "default",
        },
        _this = $(this), //表单
        ECalendar, //主面板
        day, //日期列表 
        hour, //小时列表 
        minutes, //分钟列表 
        imonth,//当前月份
        iday,//当前日期
        currentyear,//当前年份
        ilast,//日期差
        ilasttext,//天前，天后
        currentlastgo,
        ihour,//当前小时
        iminutes,//当前分钟
        select, //快速选择
        getFullYear, //选择的年份
        getMonth, //选择的月份
        getDate, //选择的日期
        weekday,//选择的星期
        getHour,//选择的小时
        getMinutes,//选择的分钟
        oper, //上下月选择 
        currenttime, //时间选择容器 
        x,y,mx,my,
        drag,
        dragnum,
        config = $.extend(con,config); 

        if(!config.format) config.format = config.type == 0 ? "yyyy-mm-dd hh:ii" : "yyyy-mm-dd";  
        init(); 
 
        _this.click(function(event){  
            var itime = _this.attr("data-ec") ? _this.attr("data-ec") : _this.val();
            var date = new Date(itime.replace(/-/g, "/"));
            if(date == 'Invalid Date') date = new Date();
            setData(date,false);

            //判断元素相对可视窗口的位置
            var top = _this.offset().top - $(document).scrollTop();
            var height = $(window).height();
            var offset = _this.offset();
            var post = _this.position(); 
            if(height/2 < top)
            {
                 ECalendar.css({
                    "left":post.left + config.offset[0],
                    "top":post.top  - config.offset[1] - ECalendar.height(),
                    "zIndex":_this.css("zIndex"),
                });
            }else
            {
                 ECalendar.css({
                    "left":post.left + config.offset[0],
                    "top":post.top + _this.outerHeight() + config.offset[1],
                    "zIndex":_this.css("zIndex"),
                });
            }
            ECalendar.show(); 
        });

        //点击外面关闭
        ECalendar.mousedown(function(event){event.stopPropagation()});
        $(document).mousedown(function(){if(ECalendar.is(":visible")) ECalendar.hide()});

        _this.on("change",function(){ 
            var date = new Date(_this.val().replace(/-/g, "/"));
            if(date == 'Invalid Date') date = new Date();
            setData(date);
        });

        //快速选择日期
        currentlastgo.click(function(){
            if(select.height() > 0) 
                select.animate({"height":0},200);
            else 
                select.animate({"height":20},200); 
        });
        select.children("li").click(function(){
             var date = new Date();
             var li = $(this);
             var index = li.index();
             if(index === 0) setData(date); 
             if(index === 1) setData(new Date(date.getFullYear(),date.getMonth(),date.getDate() + 7,date.getHours(),date.getMinutes()));
             if(index === 2) setData(new Date(date.getFullYear(),date.getMonth()+1,date.getDate(),date.getHours(),date.getMinutes()));
             if(index === 3) setData(new Date(date.getFullYear(),date.getMonth()+3,date.getDate(),date.getHours(),date.getMinutes()));
             if(index === 4) setData(new Date(date.getFullYear()+1,date.getMonth(),date.getDate(),date.getHours(),date.getMinutes()));
             select.animate({"height":0},200);
        });

        //选择日期
        day.on("mousedown","li",function(e){
            var li = $(this);
            getMonth -= 1;
            if(li.hasClass("prve")) getMonth -= 1;
            if(li.hasClass("next")) getMonth += 1;
            getDate = li.text();
            
            setData(new Date(getFullYear,getMonth,getDate,getHour,getMinutes));

            x = e.pageX;
            y = e.pageY;
            drag = $(this);
            dragnum = parseInt($(this).text());
            $("body").addClass("ECalendarNoneSelect");
            _this.attr("readonly","readonly");
        });
        
        //上下月选择
        oper.click(function(){ 
            var li = $(this);
            if(li.index() == 0) getMonth -= 2; 
            setData(new Date(getFullYear,getMonth,getDate,getHour,getMinutes));
        });

        //选择年
         

        $(imonth).mousedown(function(e){ 
            x = e.pageX;
            y = e.pageY;
            drag = $(this);
            dragnum = parseInt($(this).text());
            $("body").addClass("ECalendarNoneSelect");
            _this.attr("readonly","readonly");
        });
        $(currentyear).mousedown(function(e){ 
            x = e.pageX;
            y = e.pageY;
            drag = $(this);
            dragnum = parseInt($(this).text());
            $("body").addClass("ECalendarNoneSelect");
            _this.attr("readonly","readonly");
        }); 
        $(document).mousemove(function(e){ 
            if(drag)
            { 
                my = parseInt((e.pageY - y) / 15);
                mx = parseInt((e.pageX - x) / 15);
                if(drag[0].tagName == "LI")
                {  
                    if(Math.abs(my) > 1 || Math.abs(mx) > 1) //防误触
                    {
                        //根据坐标计算方位角
                        var ay = (e.pageX - x);
                        var ax = (y - e.pageY); 
                        var s = 90 / Math.atan(1/0);
                        var a = Math.atan(ay/ax) * s;
                        
                        if(ax < 0 && ay > 0) a = 180 + a; //第二象限
                        if(ax < 0 && ay <= 0) a = 180 + a; //第三象限
                        if(ax >= 0 && ay < 0) a = 360 + a; //第四象限
                        //console.log(ax + "==" + ay + "==" + a);

                        //根据角度算时间
                        var atime = a / 30;
                        var ahours = parseInt(atime);
                        var amin = parseInt((atime - ahours) * 60) ;
                        
                        //24小时 
                        if(Math.abs(my) > 5 || Math.abs(mx) > 5) ahours += 12;

                        getHour = ahours;
                        getMinutes = amin;
                        iminutes.text(amin < 10 ? "0" + amin : amin);
                        ihour.text(ahours < 10 ? "0" + ahours : ahours);
                    }
                    
                }else
                {
                    var m = dragnum + ((Math.abs(my) > Math.abs(mx)) ? my : mx); 
                    if(drag.hasClass("imonth"))  m = m < 1 ? 1 : (m > 12 ? 12 : m);
                    drag.text(m); 
                } 
                  
            }
            
        })
        $(document).mouseup(function(){
            if(drag)
            {  
                var m = drag.text();
                if(drag[0].tagName == "LI")
                {
                     setData(new Date(getFullYear,getMonth - 1,getDate,getHour,getMinutes));
                }else
                {
                    if(drag.hasClass("imonth")) setData(new Date(getFullYear,m - 1,getDate,getHour,getMinutes));
                    if(drag.hasClass("currentyear")) setData(new Date(m,getMonth - 1,getDate,getHour,getMinutes));
                }
                drag = false;
                $("body").removeClass("ECalendarNoneSelect");
                _this.removeAttr("readonly");
            }
        })

        //选择时间
        if(config.type == 0)
        {
             //展开选择时间
            ihour.mousedown(function(){
                minutes.stop().slideUp(200);
                hour.stop().slideDown(200);
            });
            //展开选择分钟
            iminutes.mousedown(function(){
                hour.stop().slideUp(200);
                minutes.stop().slideDown(200);
            });
            currenttime.mouseleave(function(){
                hour.stop().slideUp(200);
                minutes.stop().slideUp(200);
            });
            $("li").on("click",currenttime,function(){
                var li = $(this);
                var parent = li.parent().attr("class");
                var parent = li.parent().attr("class");
                if(parent == 'hour') 
                {
                    setData(new Date(getFullYear,getMonth - 1,getDate,li.attr("data"),getMinutes));
                    hour.stop().slideUp(200);
                    minutes.stop().slideDown(200);
                }
                if(parent == 'minutes') 
                {
                    setData(new Date(getFullYear,getMonth - 1,getDate,getHour,li.attr("data")));
                    minutes.stop().slideUp(200);
                }
            });
        }

        function init()
        {
            var html = '<div class="ECalendarBox ECalendarNoneSelect '+config.skin+'" style="display:none"><div class="head"><div class="currentdate"><h2><span class="imonth"></span>/<span class="iday"></span></h2><div class="small"><div class="currentyear"></div><div class="currentlastgo"><span class="ilast"></span><span class="ilasttext"></span></div></div><ul class="oper"><li><</li><li>></li></ul></div><ul class="select"><li>今天</li><li>一周后</li><li>一月后</li><li>三月后</li><li>一年后</li></ul><div class="currenttime"><span class="ihour"></span>:<span class="iminutes"></span><ul class="hour"><li class="arr"></li></ul><ul class="minutes"><li class="arr"></li></ul></div><ul class="week"><li>一</li><li>二</li><li>三</li><li>四</li><li>五</li><li>六</li><li>日</li></ul></div><ul class="day"></ul></div>';
           

            ECalendar = $(html);
           
            day = ECalendar.find("ul.day");
            imonth = ECalendar.find("span.imonth");
            iday = ECalendar.find("span.iday");
            currentyear = ECalendar.find("div.currentyear");
            ilast = ECalendar.find("span.ilast");
            ilasttext = ECalendar.find("span.ilasttext");
            iminutes = ECalendar.find("span.iminutes");
            ihour = ECalendar.find("span.ihour");
            hour =  ECalendar.find("ul.hour");
            minutes =  ECalendar.find("ul.minutes");
            currentlastgo = ECalendar.find("div.currentlastgo");
            select = ECalendar.find("ul.select");
            oper = ECalendar.find("ul.oper li");
            currenttime = ECalendar.find("div.currenttime");
            if(config.type == 0)
            {
                //小时列表
                var list = "";
                for(var i = 0; i<=23; i++)
                {
                    list += "<li data='"+i+"'>"+ (i < 10 ? "0"+i : i) +"</li>";
                }
                hour.append(list);
                //分钟列表
                var list = ""
                for(var i = 0; i<60; i++)
                {
                    list += "<li data='"+i+"'>"+ (i < 10 ? "0"+i : i) +"</li>";
                }
                minutes.append(list);
                currenttime.show();
            } 
            
            _this.after(ECalendar);
            var itime = _this.attr("data-ec") ? _this.attr("data-ec") : _this.val();
            var date = new Date(itime.replace(/-/g, "/"));
            if(date == 'Invalid Date') date = new Date();
            setData(date,false);
        }

        function setData(date,iscallback=true)
        { 
            getFullYear = date.getFullYear();
            getMonth = date.getMonth()+1;
            getDate = date.getDate();
            weekday = date.getDay();
            getHour = date.getHours();
            getMinutes = date.getMinutes();  
            if(ECalendar.data("date") != (getFullYear+"-"+getMonth))
            { 
                //获取当前月一号的星期
                var oneday = new Date(getFullYear, getMonth - 1,1);
                    oneday = oneday.getDay() ? oneday.getDay() : 7; 
                    oneday = oneday === 1 ? 8 : oneday;
                console.log(oneday);
                //获取当前月的总天数 
                var count = new Date(getFullYear,getMonth,0).getDate();

                //获取当前日历的最后一天
                var max = 42;

                //获取上一月的最后一天
                var prevcount = new Date(getFullYear,getMonth-1,0).getDate(); 
                
                var list = "";
                for(var i = 1; i<=max; i++)
                {
                    if(i < oneday) list += "<li class='other prve'>"+ (prevcount - (oneday - i) + 1) +"</li>";
                    else if(i >= oneday && i < count+oneday) 
                    {
                        if((i - oneday + 1) == getDate)
                            list += "<li class='activ' data='"+(i - oneday + 1)+"'>"+ (i - oneday + 1) +"</li>";
                        else
                            list += "<li data='"+(i - oneday + 1)+"'>"+ (i - oneday + 1) +"</li>";
                    }
                    else list += "<li class='other next'>"+ (i - (count + oneday) + 1) +"</li>"; 
                }
                day.html(list); 
            }

            ECalendar.find(".activ").removeClass("activ");
            day.children("li[data="+getDate+"]").addClass("activ"); 

            //获取当前时间的时间差
            var now = new Date();
            var diff = new Date(getFullYear,getMonth - 1,getDate).getTime() - new Date(now.getFullYear(),now.getMonth(),now.getDate()).getTime();
                diff = parseInt(diff/(24*3600*1000));

            ECalendar.data("date",(getFullYear+"-"+getMonth)); 
            imonth.text(getMonth);
            currentyear.text(getFullYear);
            iday.text(getDate);
            var iilasttext = "",iilast = "";
            if(diff == 0)
            {
                iilasttext = "今天";
            }
            else
            {
                iilast = Math.abs(diff);
                if(diff > 0) 
                    iilasttext = "天后";
                else
                    iilasttext = "天前";
            }
            ilasttext.text(iilasttext);
            ilast.text(iilast);

            if(config.type == 0)
            {
                hour.children("li[data="+getHour+"]").addClass("activ");
                minutes.children("li[data="+getMinutes+"]").addClass("activ");
                iminutes.text(getMinutes < 10 ? "0"+getMinutes : getMinutes);
                ihour.text(getHour < 10 ? "0"+getHour : getHour);
            }

            var val = config.format.replace('yyyy', getFullYear).replace('mm', getMonth).replace('dd', getDate).replace('hh', getHour).replace('ii', getMinutes); 
            _this.attr("data-ec",date);
            _this.val(val);
            if(iscallback && config.callback) config.callback(date);
        }
    }